#include "qmc2sserverdialog.h"
#include "ui_qmc2sserverdialog.h"
#include "thread.h"
#include "def.h"
#include "screentestthread.h"
#include "report.h"
#include <QProcess>
#include <windows.h>
#include <QDir>
#include <QJsonArray>
#include <QJsonDocument>

void static log_print(QString info)
{
    QFile file(QDate::currentDate().toString("yyyy-M-d") + ".log");
    if(!file.open(QIODevice::Append | QIODevice::Text ))
    {
        return;
    }
    QTextStream log_info(&file);

    log_info<<QDateTime::currentDateTime().toString("yyyy-m-d hh:mm:ss")<<"\t"<<info<<"\n";
    file.close();
}

QMC2SServerDialog::QMC2SServerDialog(QWidget *parent) :
    QDialog(parent),flag(true),dev_test_count(0), device_count(0),
    ui(new Ui::QMC2SServerDialog)
{
    ui->setupUi(this);

    QFile file("config.ini");
    settings = new QSettings("config.ini",  QSettings::IniFormat);

    QString language = settings->value("language").toString();
    if(language == "en")
    {
        ui->language_comboBox->setCurrentIndex(1);
    }
    else
    {
        ui->language_comboBox->setCurrentIndex(0);
    }

    if(!file.exists())
    {
        config.db_host = "localhost";
        config.db_name = "dev_monitor";
        config.db_port = 3306;
        config.db_user = "root";
        config.db_pass = "123qwe";

        settings->setValue("db_host", config.db_host);
        settings->setValue("db_port", config.db_port);
        settings->setValue("db_name", config.db_name);
        settings->setValue("db_user", config.db_user);
        settings->setValue("db_pass", config.db_pass);
    }
    else
    {
        config.db_host = settings->value("db_host").toString();
        config.db_port = settings->value("db_port").toInt();
        config.db_name = settings->value("db_name").toString();
        config.db_user = settings->value("db_user").toString();
        config.db_pass = settings->value("db_pass").toString();
    }

    ui->db_hostLineEdit->setText(config.db_host);
    ui->db_nameLineEdit->setText(config.db_name);
    QString port;
    port.setNum(config.db_port);
    ui->db_portLineEdit->setText(port);
    ui->db_userLineEdit->setText(config.db_user);
    ui->db_passLineEdit->setText(config.db_pass);

    // 判断当前系统是否支持系统脱盘图标
    if (!QSystemTrayIcon::isSystemTrayAvailable()) {
        QMessageBox::critical(0, QObject::tr("QMC2SSERVER"),
                              QObject::tr("QMC2S-100 Server couldn't detect any system tray "
                                          "on this system."));
        return;
    }
    QIcon icon = QIcon(":/images/png-0688.png");
    setWindowIcon(icon);
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(icon);
    trayIcon->setToolTip("在这里");
    createActions();
    createTrayIcon();
    trayIcon->show();
    setWindowTitle(tr("QMC2S-100 测试服务器控制台"));


    connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
    connect(ui->backButton, SIGNAL(clicked()), this, SLOT(showMessage()));
    connDB();
    init();
    // 发送邮件
    report = new Report(NULL, &db);

    QSettings *settings = new QSettings("config.ini", QSettings::IniFormat);
    user = settings->value("EMAIL/user_name").toString();
    password = settings->value("EMAIL/pass_word").toString();
    host = settings->value("EMAIL/email_server").toString();
    port = settings->value("EMAIL/email_server_port").toInt();
    to = settings->value("EMAIL/recpt").toString();
    from = settings->value("EMAIL/user_name").toString();
    smtp = new Smtp(user, password, host);
    delete settings;

    // 服务器
    tcpServer.listen(QHostAddress::Any, 10003);
    connect(&tcpServer, SIGNAL(newConnection()), this, SLOT(newConnect()));

}

void QMC2SServerDialog::start_process()
{
    ui->textEdit->append(tr("process start"));
}

void QMC2SServerDialog::finish_process(int exitCode, QProcess::ExitStatus exitStatus)
{
    if (exitStatus == QProcess::NormalExit)
    {
        ui->textEdit->append(tr("process exit normal"));
    }
    else
    {
        ui->textEdit->append(tr("process exit crash"));
    }
    ui->textEdit->append("process finised");
}

void QMC2SServerDialog::start_read_output()
{
    QByteArray ba = process->readAllStandardOutput();
    ui->textEdit->append(ba);
}

void QMC2SServerDialog::start_read_err_output()
{
    QByteArray ba = process->readAllStandardError();
    ui->textEdit->append("error: " + ba);
}

void QMC2SServerDialog::log_print_msg(const QString str)
{
//    ui->textEdit->append(str+"\n");
    log_print( str);
}

void QMC2SServerDialog::doTimer()
{
    QTcpSocket tcpSocket;
    char getFtl[30]={"lss100.sys.ftl\r"};

}

void QMC2SServerDialog::start()
{
    ScreenTest();

    for(int i = 0; i<dev_list.size(); i++)
    {
        ths[i].setDB(db);
        ths[i].setDevice(dev_list[i]);
        ths[i].Stop(false);
        if(ui->sisRadioButton->isChecked())
        {
            ths[i].setTestModel(WANDA_MODEL);
        }
        else if(ui->interruptRadioButton)
        {
            ths[i].setTestModel(SERVER_MODEL);
        }
        else
        {
            ths[i].setTestModel(LEONIS_MODEL);
        }

        connect(&ths[i], SIGNAL(send_msg(QString)), this, SLOT(receive_msg(QString)));
        connect(&ths[i], SIGNAL(log_info(QString)), this, SLOT(log_print_msg(QString)));
        connect(&ths[i], SIGNAL(proc_sql(QString)), this, SLOT(execQuery(QString)));
        connect(&ths[i], SIGNAL(send_progress_value(int)), this, SLOT(receive_progress_value(int)) );
        ths[i].Stop(false);
        ths[i].start();
    }

    connect(report, SIGNAL(log_info(QString)), this, SLOT(log_print_msg(QString)));
    process = new QProcess;
    connect(process, SIGNAL(started()), this, SLOT(start_process()));
    connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(start_read_output()));
    connect(process, SIGNAL(readyReadStandardError()), this, SLOT(start_read_err_output()));
    connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finish_process(int, QProcess::ExitStatus)));

}

void QMC2SServerDialog::stop()
{
    if(!ui->stopButton->isEnabled())return;
    flag = false;
    ui->startButton->setEnabled(true);
    ui->stopButton->setEnabled(false);
    for(int i = 0; i<dev_list.size(); i++)
    {
        ths[i].Stop(true);
    }
    report->stopped = true;
}

void QMC2SServerDialog::deamon()
{
    ScreenTest();

    for(int i = 0; i<dev_list.size(); i++)
    {
        ths[i].setDB(db);
        ths[i].setDevice(dev_list[i]);
        ths[i].Stop(false);
        if(ui->sisRadioButton->isChecked())
        {
            ths[i].setTestModel(WANDA_MODEL);
        }
        else if(ui->interruptRadioButton->isChecked())
        {
            ths[i].setTestModel(SERVER_MODEL);
        }
        else
        {
            ths[i].setTestModel(LEONIS_MODEL);
        }

        connect(&ths[i], SIGNAL(send_msg(QString)), this, SLOT(receive_msg(QString)));
        connect(&ths[i], SIGNAL(log_info(QString)), this, SLOT(log_print_msg(QString)));
        connect(&ths[i], SIGNAL(proc_sql(QString)), this, SLOT(execQuery(QString)));
        connect(&ths[i], SIGNAL(send_progress_value(int)), this, SLOT(receive_progress_value(int)) );
        ths[i].Stop(false);
        ths[i].start();
    }
    report = new Report(NULL, &db);
    connect(report, SIGNAL(log_info(QString)), this, SLOT(log_print_msg(QString)));
    process = new QProcess;
    connect(process, SIGNAL(started()), this, SLOT(start_process()));
    connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(start_read_output()));
    connect(process, SIGNAL(readyReadStandardError()), this, SLOT(start_read_err_output()));
    connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finish_process(int, QProcess::ExitStatus)));
}

void QMC2SServerDialog::closeEvent(QCloseEvent *event)
{

    if (trayIcon->isVisible())
    {
        hide();
        event->ignore();
    }
    else
        event->accept();
}

void QMC2SServerDialog::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    //触发后台图标执行相应事件
    switch (reason)
    {
    case QSystemTrayIcon::Trigger:
        //           showMessage("鼠标单击！");
        break;
    case QSystemTrayIcon::DoubleClick:
        showNormal();
        //           showMessage("鼠标双击！");
        break;
    case QSystemTrayIcon::MiddleClick:
        //           showMessage("鼠标中键！");
        break;
    default:
        break;
    }
}

void QMC2SServerDialog::showMessage()
{
    QString titlec=tr("QMC2S-100 控制台在这里");
    QString textc=tr("右击选择操作");
    trayIcon->showMessage(titlec, textc, QSystemTrayIcon::Information, 5000);
}

void QMC2SServerDialog::showMessage(char *msg)
{

    QString titlec=tr(msg);
    QString textc=QString::fromLocal8Bit("测试内容单击、双击、中键、按钮");
    trayIcon->showMessage(titlec, textc, QSystemTrayIcon::Information, 5000);
    hide();

}

void QMC2SServerDialog::execQuery(QString sql)
{
    model->setQuery(sql, db);
    if(model->lastError().isValid())
    {
        alert(sql);
        ui->textEdit->append(model->lastError().text() + "\n");
        return ;
    }
}


void QMC2SServerDialog::createActions()
{
    minimizeAction = new QAction(tr("最小化 (&I)"), this);
    connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
    maximizeAction = new QAction(tr("最大化 (&X)"), this);
    connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
    restoreAction = new QAction(tr("还原 (&R)"), this);
    connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
    quitAction = new QAction(tr("退出 (&Q)"), this);
    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
    startAction = new QAction(tr("启动"), this);
    connect(startAction, SIGNAL(triggered()), this, SLOT(on_startButton_clicked()));
    stopAction = new QAction(tr("停止"), this);
    connect(stopAction, SIGNAL(triggered()), this, SLOT(on_stopButton_clicked()));

}

void QMC2SServerDialog::createTrayIcon()
{
    //设置右键点击时弹出的菜单
    trayIconMenu = new QMenu(this);
    trayIconMenu->addAction(minimizeAction);
    trayIconMenu->addAction(maximizeAction);
    trayIconMenu->addAction(restoreAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(startAction);
    trayIconMenu->addAction(stopAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(quitAction);
    trayIcon->setContextMenu(trayIconMenu);
}


QMC2SServerDialog::~QMC2SServerDialog()
{
    delete ui;
}

void QMC2SServerDialog::init()
{

    model = new QSqlQueryModel(this);
    QString sql = tr("select count(*) from tb_dev_corrected_value_conf");
    model->setQuery(sql, db);
    if(model->lastError().isValid())
    {
        alert(model->lastError().text());
        return ;
    }
    device_count = model->data(model->index(0, 0)).toInt();

    sql = tr("select cinema_hall, dev_ip, fix_ftl, fix_lc, fix_rc, fix_cc, fix_hb, fix_la, fix_ra, start_datetime, end_datetime from tb_dev_corrected_value_conf ");
    model->setQuery(sql, db);
    if(model->lastError().isValid())
    {
        QMessageBox::information(this, tr("错误"), tr("执行SQL失败"));
        qDebug()<<"sql==="<<sql<<endl;
    }
    dev_list.clear();
    Device dev;
    for(int i = 0; i<model->rowCount(); i++)
    {
        dev.theaterNo = model->data(model->index(i, 0)).toString();
        dev.ip = model->data(model->index(i, 1)).toString();
        dev.port = 10001;
        dev.fix_ftl = model->data(model->index(i, 2)).toDouble();
        dev.fix_lc = model->data(model->index(i, 3)).toDouble();
        dev.fix_rc = model->data(model->index(i, 4)).toDouble();
        dev.fix_cc = model->data(model->index(i, 5)).toDouble();
        dev.fix_hb = model->data(model->index(i, 6)).toDouble();
        dev.fix_la = model->data(model->index(i, 7)).toDouble();
        dev.fix_ra = model->data(model->index(i, 8)).toDouble();
        dev.stime = model->data(model->index(i, 9)).toTime();
        dev.etime = model->data(model->index(i, 10)).toTime();
        dev_list.push_back(dev);
    }
}

void QMC2SServerDialog::connDB()
{
    db = QSqlDatabase::addDatabase("QMYSQL");
    QSqlError sqlerr = db.lastError();
    if (sqlerr.type() != QSqlError::NoError)
    {
        printf("DATABASE INIT ERROR: %s\n", sqlerr.text().toStdString().c_str());
        QMessageBox::information(this, tr("Db Error"), tr("Failed to connect mysql"));
        //       exit(-1);
        return ;
    }
    db.setHostName(config.db_host);
    db.setPort(config.db_port);
    db.setDatabaseName(config.db_name);
    db.setUserName(config.db_user);
    db.setPassword(config.db_pass);

    if (!db.open())
    {
        printf("DATABASE CONNECTION ERROR: %s\n", db.lastError().text().toStdString().c_str());
        QMessageBox::information(this, tr(" db open Error"), tr("Failed to open database."));
        //       exit(-1);
        return ;
    }
}

void QMC2SServerDialog::do_send_email(const QString file)
{
    QStringList files;
    QString subject = QDateTime::currentDateTime().toString("YYYY-MM-dd hh:mm:ss") + tr("影厅监测数据 ");
    files.append(file);
    if( !files.isEmpty() )
    {
        smtp->sendMail(from, to , subject, "这封邮件由LEONIS CINEMA 出口QMC2S-100 自动发送.", files );
    }
    else
    {
        smtp->sendMail(from, to, subject, "hello, there are not attachment\n");
    }
}

void QMC2SServerDialog::on_startButton_clicked()
{

    if(!ui->startButton->isEnabled())return;

    ui->startButton->setEnabled(false);
    ui->stopButton->setEnabled(true);
    flag = true;



    config.db_host = ui->db_hostLineEdit->text().trimmed();
    config.db_port = ui->db_portLineEdit->text().trimmed().toInt();
    config.db_name = ui->db_nameLineEdit->text().trimmed();
    config.db_user = ui->db_userLineEdit->text().trimmed();
    config.db_pass = ui->db_passLineEdit->text().trimmed();
    settings->setValue("db_host", config.db_host);
    settings->setValue("db_port", config.db_port);
    settings->setValue("db_name", config.db_name);
    settings->setValue("db_user", config.db_user);
    settings->setValue("db_pass", config.db_pass);
    deamon();
}
void QMC2SServerDialog::newConnect()
{
    tcpSocket = tcpServer.nextPendingConnection(); //得到每个连进来的socket
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readMessage())); //有可读的信息，触发读函数槽
}

void QMC2SServerDialog::readMessage()
{
    QSettings *settings = new QSettings("config.ini", QSettings::IniFormat);
    QByteArray qba= tcpSocket->readAll(); //读取
    qDebug()<<qba;
    QString ss=QVariant(qba).toString();
    if(ss == "status")
    {
        QString server_model = settings->value("SERVER_MODEL").toString();
        tcpSocket->write(server_model.toLocal8Bit().data());
        if(!tcpSocket->waitForBytesWritten())
        {
            ui->textEdit->append(tr("向客户端响应数据出错"));
        }
        return;
    }
    if(ss == "polling")
    {
        settings->setValue("SERVER_MODEL", "polling");
        ui->pollingRadioButton->setChecked(true);
        ui->sisRadioButton->setChecked(false);
        ui->interruptRadioButton->setChecked(false);
        ui->sensorRadioButton->setChecked(false);

        // start polling

    }
    else if(ss == "sis")
    {
        settings->setValue("SERVER_MODEL", "sis");
        // start sis
        ui->pollingRadioButton->setChecked(false);
        ui->sisRadioButton->setChecked(true);
        ui->interruptRadioButton->setChecked(false);
        ui->sensorRadioButton->setChecked(false);

    }
    else if(ss == "sensor")
    {
        settings->setValue("SERVER_MODEL", "sensor");
        // start server.
        ui->pollingRadioButton->setChecked(false);
        ui->sisRadioButton->setChecked(false);
        ui->interruptRadioButton->setChecked(false);
        ui->sensorRadioButton->setChecked(true);

    }
    else if(ss == "stop")
    {
        stop();
    }
    else
    {
        settings->setValue("SERVER_MODEL", "interrupt");
        // start interrupt
        ui->pollingRadioButton->setChecked(false);
        ui->sisRadioButton->setChecked(false);
        ui->interruptRadioButton->setChecked(true);
        ui->sensorRadioButton->setChecked(false);
    }

    stop();
    start();

    tcpSocket->close();


}

void QMC2SServerDialog::alert(QString msg)
{
    QMessageBox::information(this, "", msg);
}

void QMC2SServerDialog::ScreenTest()
{
    QString sql = tr("select count(*) from screen_test_setup ");
    model->setQuery(sql, db);
    if(model->lastError().isValid())
    {
        alert(model->lastError().text());
        return ;
    }
    if(model->rowCount() <= 0  )
    {
        return;
    }

    ScreenTestThread *screenTestThread = new ScreenTestThread(this, &db);
    connect(screenTestThread, SIGNAL(log_info(QString)), this, SLOT(log_print_msg(QString)));
    screenTestThread->start();
}



void QMC2SServerDialog::receive_msg(const QString str)
{
    QMessageBox::information(this, "", str);
    stop();
    return;


}

void QMC2SServerDialog::receive_progress_value(const int value)
{
    dev_test_count = dev_test_count + value;

    if(dev_test_count == device_count )
    {
        ui->textEdit->clear();
        report->start();
        dev_test_count = 0;
        ui->textEdit->append(QDir::currentPath() + "\\EmailDemo.exe");
        process->start("EmailDemo.exe");
        if(!process->waitForStarted())
        {
            ui->textEdit->append(tr("启动失败"));
            return ;
        }
        if(!process->waitForFinished(3000))
        {
            ui->textEdit->append(tr("finished error.\n"));
        }
        process->close();
    }
}

void QMC2SServerDialog::on_stopButton_clicked()
{
    if(!ui->stopButton->isEnabled())return;
    flag = false;
    ui->startButton->setEnabled(true);
    ui->stopButton->setEnabled(false);
    for(int i = 0; i<dev_list.size(); i++)
    {
        ths[i].Stop(true);
    }
    report->stopped = true;
}

void QMC2SServerDialog::on_exitButton_clicked()
{
    exit(0);
}

void QMC2SServerDialog::on_backButton_clicked()
{
    close();
}

void QMC2SServerDialog::on_language_comboBox_currentTextChanged(const QString &arg1)
{
    if(arg1 == "中文简体")
    {
        settings->setValue("language", "cn");
    }
    else
    {
        settings->setValue("language", "en");
    }
}


void QMC2SServerDialog::on_serverRadioButton_clicked()
{
    ServerForm *serverForm = new ServerForm(NULL, &db);
    serverForm->show();
}
